package org.lib.mysqlhello.security.self;

import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Transient;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * 自定义用户
 * @author ben
 * @date 2021-09-05 09:26:11 CST
 */
@Entity
@DynamicInsert
@DynamicUpdate
@Data
@Slf4j
public class AppUser implements UserDetails {

	private static final long serialVersionUID = 210905L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column(columnDefinition = "VARCHAR(50) NOT NULL UNIQUE")
	private String username;
	
	@Column(columnDefinition = "VARCHAR(384) NOT NULL")
	private String password;

	/**
	 * 用户角色
	 * 多个角色使用英文都好（,）隔开
	 */
	@Column(columnDefinition = "VARCHAR(500) NOT NULL")
	private String roles;

	/**
	 * 角色名前缀：数据库中
	 */
	public static final String ROLES_PREFIX = "ROLE_";
	
	/**
	 * 角色分隔符：英文逗号
	 */
	public static final String ROLES_SEP = ",";
	
	/**
	 * 用户是否启用：默认启用
	 */
	@Column(columnDefinition = "BIT(1) DEFAULT true")
	private Boolean enabled;

	/**
	 * 有效期时间戳（单位：毫秒）
	 * 默认为0 永久有效
	 * 这个时间点前有效
	 */
	@Column(columnDefinition = "BIGINT DEFAULT 0")
	private Long expiration;
	
	/**
	 * 创建时间
	 */
	@Column(insertable = false, columnDefinition = "DATETIME DEFAULT NOW()")
	private Date createTime;
	
	/**
	 * 更新时间
	 */
	@Column(insertable = false, updatable = false, columnDefinition = "DATETIME DEFAULT NOW() ON UPDATE NOW()")
	private Date updateTime;

	// ----实现UserDetails接口----
	
	// set函数已使用 @Data 注解建立
	@Transient
	private List<GrantedAuthority> authorities;
	
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return authorities;
	}

	@Override
	public boolean isAccountNonExpired() {
		if (this.expiration <= 0 || this.expiration >= System.currentTimeMillis()) {
			return true;
		}
		
		log.warn("用户过期：id={}, expiration={}", this.id, this.expiration);
		return false;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		return this.enabled;
	}
	
	// ----实现UserDetails接口----
	
}
